﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvcShop.Models;
using MvcShop.Models.Repositories;
using MvcShop.Core.Architecture.Cache;

namespace MvcShop.MVC.Services
{
    public static class AccountService
    {
        private static SouthShopEntities1 Service { get { return BaseRepository.sse; } }
        private static IMsCache MsCache { get { return (IMsCache)MvcApplication.Container["msCache"]; } }

        public static bool IsAllowed(Role role, string controllerName, string actionName)
        {
            IEnumerable<ControllerAction> cas;
            if (!MsCache.TryGet("ControllerActions", out cas))
            {
                try
                {
                    cas = Service.ControllerActions.ToList();
                    var _ExpireTime = DateTime.Now.AddMinutes(30);//指定30分钟后过期
                    MsCache.Set<IEnumerable<ControllerAction>>("ControllerActions", cas, _ExpireTime);
                }
                catch (Exception e)
                {
                    throw new Exception(e.Message);
                }
            }


            // 获取对应的controller
            var controller = (cas.Where(c => c.Name == controllerName)).Where(c => c.IsControler).Select(c => c).First();
            if (controller != null)
            { 
                // 获取对应的action 
                var controllerAction = ((cas.Where(c => c.Name == actionName)).Where(c => c.IsControler == false)).Where(c => c.ControlerName == controllerName).Select(c=>c).First();
                return controllerAction == null ? isAllowed(role, controller) : isAllowed(role, controllerAction); 
            }

            return true;
        }

        public static bool isAllowed(Role role, ControllerAction controllerAction)
        {
            IEnumerable<ControllerActionRole> cars;
            string userCAR = role.RoleId + "_ControllerActionRole";
            if (!MsCache.TryGet(userCAR, out cars))
            {
                try
                {
                    cars = Service.ControllerActionRoles.Where(c => c.RoleId == role.RoleId).Select(c => c).ToList();
                    var _ExpireTime = DateTime.Now.AddMinutes(30);//指定30分钟后过期
                    MsCache.Set<IEnumerable<ControllerActionRole>>(userCAR, cars, _ExpireTime);
                }
                catch (Exception e)
                {
                    throw new Exception(e.Message);
                }
            }


            // 允许没有角色的：也就是说允许所有人，包括没有登录的用户 
            if (controllerAction.IsAllowedNoneRoles)
            {
                return true;
            }

            // 允许所有角色：只要有角色，就可以访问 
            if (controllerAction.IsAllowedAllRoles)
            {
                if (role == null)
                {
                    return false;
                }

                return true;
            }    

            // 选出action对应的角色 
            var roles = cars.Where(c=>c.ControlerActionId==controllerAction.ControllerActionId).Select(c=>c).ToList();
            if (roles.Count == 0)
            {
                // 角色数量为0，也就是说没有定义访问规则，默认允许访问 
                return true;
            }

            //查找有没有当前用户所对应的角色
            var HavedRolesids = roles.Find(c=>c.RoleId==role.RoleId);
            if (HavedRolesids == null)
            {
                //找不到当前用户所对应的角色，不允许访问
                return false;
            }

            //只有允许旂角色才可以访问 
            if (HavedRolesids.IsAllowed)
            {
                return true;
            }
            
            return false;
        }
    }
}
